#include <boost/smart_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include "weak_ptr_caller.h"

class slave
{
public:
    typedef boost::shared_ptr< slave > ptr;
    typedef boost::function< void ( const char * ) > callback;

    void set( const callback & cb )
    {
        _cb = cb;
    }

    void call( const char * str ) const
    {
        if( _cb )
            _cb( str );
    }

private:
    callback _cb;
};

class master: public boost::enable_shared_from_this< master >
{
public:
    typedef boost::shared_ptr< master > ptr;
    typedef boost::weak_ptr< master > wptr;

    void set( const slave::ptr slave_ )
    {
        _slave = slave_;
        if( _slave )
            _slave->set( boost::bind( &master::handler, master::wptr( shared_from_this() ), _1 ) );
    }

private:
    void handler( const char * str )
    {
        std::cout << str << std::endl;
    };

    slave::ptr _slave;
};

int main()
{
    // create master and slave
    master::ptr master_( new master() );
    slave::ptr slave_( new slave() );

    // give the slave to the master
    master_->set( slave_ );

    // call slave's function, should cause master's callback to print something
    slave_->call( "hello" );

    // now kill the master
    master_.reset();

    // call the function again
    try
    {
        slave_->call( "hey" );
    }
    catch( boost::bad_weak_ptr & e )
    {
        std::cout << "exception: " << e.what() << std::endl;
    }

    // use this in a worker thread?

	return 0;
}
